package com.loong.ems.config;


import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.loong.ems.utils.IdWorker;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.LogoutConfigurer;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
/**
 * @author 龙勇-229970722
 * @date 2025-01-02 8:52
 * @description: Security配置类
 */


@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {

      /**
     * 定义密码加密、匹配bean
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    /**
     * 基于雪花算法的工具类
     * @return
     */
    @Bean
    public IdWorker idWorker(){
        /**
         * 参数1：机器ID
         * 参数2：机房ID
         */
        return new IdWorker(1L,1L);
    }

    /**
     * 统一定义long序列化转String设置
     *
     * 此方法配置了一个MappingJackson2HttpMessageConverter实例，用于全局统一处理HTTP消息转换
     * 主要目的是将Long类型的数据在序列化时转换为String，避免大数值转换为JSON时的精度丢失问题
     *
     * @return MappingJackson2HttpMessageConverter 返回配置好的HTTP消息转换器实例
     */
    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
        // 创建HTTP消息转换器实例
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();

        // 创建ObjectMapper实例，用于JSON序列化和反序列化
        ObjectMapper objectMapper = new ObjectMapper();

        // 配置反序列化设置，忽略JSON中存在但在Java对象中不存在的属性
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

        // 创建一个简单的模块，用于注册自定义的序列化器
        SimpleModule simpleModule = new SimpleModule();

        // 注册Long类型的序列化器，将Long类型的数据转换为String类型
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);

        // 将自定义模块注册到ObjectMapper中
        objectMapper.registerModule(simpleModule);

        // 将配置好的ObjectMapper设置到HTTP消息转换器中
        converter.setObjectMapper(objectMapper);

        // 返回配置好的HTTP消息转换器实例
        return converter;
    }

    /**
     * 配置Spring Security的安全过滤链
     *
     * @param http HttpSecurity对象，用于配置安全策略
     * @return SecurityFilterChain 返回构建好的安全过滤链
     * @throws Exception 如果配置过程中发生异常
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .authorizeHttpRequests(authorize -> authorize
                        .requestMatchers("/user/login").permitAll() // 允许匿名用户访问登录接口
                        .requestMatchers("/**").permitAll() // 允许匿名用户访问登出接口
                        .requestMatchers("/user/register").permitAll() // 允许匿名用户访问注册接口
                        .requestMatchers("/doc.html", "/webjars/**", "/swagger-resources/**","/swagger-ui.html",
                                "/v3/api-docs", "/v3/api-docs/**", "/swagger-ui/**").permitAll() // 放行Swagger相关的路径
                        .anyRequest().authenticated() // 其他所有请求都需要认证
                )
                .csrf(csrf -> csrf.disable()); // 禁用CSRF保护

        return http.build();
    }




}
